home *** CD-ROM | disk | FTP | other *** search
/ Freelog 115 / FreelogNo115-MaiJuin2013.iso / Internet / Filezilla Server / FileZilla_Server-0_9_41.exe / source / interface / splitex.cpp < prev    next >
C/C++ Source or Header  |  2011-11-06  |  11KB  |  465 lines

  1. ////////////////////////////////////////////////////////////////////////////
  2. //
  3. // splitex.cpp
  4. // Based upon code from Oleg G. Galkin
  5. // Modified to handle multiple hidden rows
  6.  
  7. #include "stdafx.h"
  8. #include "splitex.h"
  9.  
  10. #if defined(_DEBUG) && !defined(MMGR)
  11. #define new DEBUG_NEW
  12. #undef THIS_FILE
  13. static char THIS_FILE[] = __FILE__;
  14. #endif
  15.  
  16. ////////////////////////////////////////////////////////////////////////////
  17. //
  18. // CSplitterWndEx
  19.  
  20. CSplitterWndEx::CSplitterWndEx()
  21. {
  22.     m_arr = 0;
  23.     m_length = 0;
  24. }
  25.  
  26. CSplitterWndEx::~CSplitterWndEx()
  27. {
  28.     delete [] m_arr;
  29. }
  30.  
  31. int CSplitterWndEx::Id_short(int row, int col)
  32. {
  33.     return AFX_IDW_PANE_FIRST + row * 16 + col;
  34. }
  35.  
  36. void CSplitterWndEx::ShowRow(int r)
  37. {
  38.     ASSERT_VALID(this);
  39.     ASSERT(m_nRows < m_nMaxRows);
  40.  
  41.     ASSERT(m_arr);
  42.     ASSERT(r < m_length);
  43.     ASSERT(m_arr[r] >= m_nRows);
  44.     ASSERT(m_arr[r] < m_length);
  45.  
  46.     int rowNew = r;
  47.     int cyNew = m_pRowInfo[m_arr[r]].nCurSize;
  48.     int cyIdealNew = m_pRowInfo[m_arr[r]].nIdealSize;
  49.     
  50.     int new_val = 0;
  51.  
  52.     for (int i = rowNew - 1; i >= 0; i--)
  53.         if (m_arr[i] < m_nRows)    // not hidden
  54.         {
  55.             new_val = m_arr[i] + 1;
  56.             break;
  57.         }
  58.  
  59.     int old_val = m_arr[rowNew];
  60.  
  61.     m_nRows++;  // add a row
  62.  
  63.     // fill the hided row
  64.     int row;
  65.     for (int col = 0; col < m_nCols; col++)
  66.     {
  67.         CWnd* pPaneShow = GetDlgItem(
  68.             Id_short(old_val, col));
  69.         ASSERT(pPaneShow != NULL);
  70.         pPaneShow->ShowWindow(SW_SHOWNA);
  71.  
  72.         for (row = m_length - 1; row >= 0; row--)
  73.         {
  74.             if ((m_arr[row] >= new_val) &&
  75.                 (m_arr[row] < old_val))
  76.             {
  77.                 CWnd* pPane = CSplitterWnd::GetPane(m_arr[row], col);
  78.                 ASSERT(pPane != NULL);
  79.                 pPane->SetDlgCtrlID(Id_short(m_arr[row] + 1, col));
  80.             }
  81.         }
  82.         pPaneShow->SetDlgCtrlID(Id_short(new_val, col));
  83.     }
  84.  
  85.     for (row = 0; row < m_length; row++)
  86.         if ((m_arr[row] >= new_val) &&
  87.             (m_arr[row] < old_val))
  88.             m_arr[row]++;
  89.  
  90.     m_arr[rowNew] = new_val;
  91.  
  92.     //new panes have been created -- recalculate layout
  93.     for (row = new_val + 1; row < m_length; row++)
  94.     {
  95.         if (m_arr[row]<m_nRows)
  96.         {
  97.             m_pRowInfo[m_arr[row]].nIdealSize = m_pRowInfo[m_arr[row-1]].nCurSize;
  98.             m_pRowInfo[m_arr[row]].nCurSize = m_pRowInfo[m_arr[row-1]].nCurSize;
  99.         }
  100.     }
  101.     if (cyNew>=0x10000)
  102.     {
  103.         int rowToResize=(cyNew>>16)-1;
  104.         cyNew%=0x10000;
  105.         cyIdealNew%=0x10000;
  106.         m_pRowInfo[m_arr[rowToResize]].nCurSize-=cyNew+m_cxSplitter;
  107.         m_pRowInfo[m_arr[rowToResize]].nIdealSize=m_pRowInfo[m_arr[rowToResize]].nCurSize;//-=cyIdealNew+m_cxSplitter;
  108.     }
  109.  
  110.     m_pRowInfo[new_val].nIdealSize = cyNew;
  111.     m_pRowInfo[new_val].nCurSize = cyNew;
  112.     RecalcLayout();
  113. }
  114.  
  115. void CSplitterWndEx::ShowColumn(int c)
  116. {
  117.     ASSERT_VALID(this);
  118.     ASSERT(m_nCols < m_nMaxCols);
  119.  
  120.     ASSERT(m_arr);
  121.     ASSERT(c < m_length);
  122.     ASSERT(m_arr[c] >= m_nRows);
  123.     ASSERT(m_arr[c] < m_length);
  124.  
  125.     int colNew = c;
  126.     int cxNew = m_pColInfo[m_arr[c]].nCurSize;
  127.     int cxIdealNew = m_pColInfo[m_arr[c]].nIdealSize;
  128.     
  129.     int new_val = 0;
  130.  
  131.     for (int i = colNew - 1; i >= 0; i--)
  132.         if (m_arr[i] < m_nCols)    // not hidden
  133.         {
  134.             new_val = m_arr[i] + 1;
  135.             break;
  136.         }
  137.  
  138.     int old_val = m_arr[colNew];
  139.  
  140.     m_nCols++;  // add a col
  141.  
  142.     // fill the hided col
  143.     int col;
  144.     for (int row = 0; row < m_nRows; row++)
  145.     {
  146.         CWnd* pPaneShow = GetDlgItem(
  147.             Id_short(row, old_val));
  148.         ASSERT(pPaneShow != NULL);
  149.         pPaneShow->ShowWindow(SW_SHOWNA);
  150.  
  151.         for (col = m_length - 1; col >= 0; col--)
  152.         {
  153.             if ((m_arr[col] >= new_val) &&
  154.                 (m_arr[col] < old_val))
  155.             {
  156.                 CWnd* pPane = CSplitterWnd::GetPane(row, m_arr[col]);
  157.                 ASSERT(pPane != NULL);
  158.                 pPane->SetDlgCtrlID(Id_short(row, m_arr[col]+1));
  159.             }
  160.         }
  161.         pPaneShow->SetDlgCtrlID(Id_short(row, new_val));
  162.     }
  163.  
  164.     for (col = 0; col < m_length; col++)
  165.         if ((m_arr[col] >= new_val) &&
  166.             (m_arr[col] < old_val))
  167.             m_arr[col]++;
  168.  
  169.     m_arr[colNew] = new_val;
  170.  
  171.     //new panes have been created -- recalculate layout
  172.     for (col = new_val + 1; col < m_length; col++)
  173.     {
  174.         if (m_arr[col]<m_nCols)
  175.         {
  176.             m_pColInfo[m_arr[col]].nIdealSize = m_pColInfo[m_arr[col-1]].nCurSize;
  177.             m_pColInfo[m_arr[col]].nCurSize = m_pColInfo[m_arr[col-1]].nCurSize;
  178.         }
  179.     }
  180.     if (cxNew>=0x10000)
  181.     {
  182.         int colToResize=(cxNew>>16)-1;
  183.         cxNew%=0x10000;
  184.         cxIdealNew%=0x10000;
  185.         m_pColInfo[m_arr[colToResize]].nCurSize-=cxNew+m_cySplitter;
  186.         m_pColInfo[m_arr[colToResize]].nIdealSize=m_pColInfo[m_arr[colToResize]].nCurSize;//-=cxIdealNew+m_cySplitter;
  187.     }
  188.  
  189.     m_pColInfo[new_val].nIdealSize = cxNew;
  190.     m_pColInfo[new_val].nCurSize = cxNew;
  191.     RecalcLayout();
  192. }
  193.  
  194. void CSplitterWndEx::HideRow(int rowHide,int rowToResize)
  195. {
  196.     ASSERT_VALID(this);
  197.     ASSERT(m_nRows > 1);
  198.  
  199.     if (m_arr)
  200.         ASSERT(m_arr[rowHide] < m_nRows);
  201.  
  202.     // if the row has an active window -- change it
  203.     int rowActive, colActive;
  204.  
  205.     if (!m_arr)
  206.     {
  207.         m_arr = new int[m_nRows];
  208.         for (int i = 0; i < m_nRows; i++)
  209.             m_arr[i] = i;
  210.         m_length = m_nRows;
  211.     }
  212.  
  213.     if (GetActivePane(&rowActive, &colActive) != NULL &&
  214.         rowActive == rowHide) //colActive == rowHide)
  215.     {
  216.         if (++rowActive >= m_nRows)
  217.             rowActive = 0;
  218.         //SetActivePane(rowActive, colActive);
  219.  
  220.         SetActivePane(rowActive, colActive);
  221.     }
  222.  
  223.     // hide all row panes
  224.     for (int col = 0; col < m_nCols; col++)
  225.     {
  226.         CWnd* pPaneHide = CSplitterWnd::GetPane(m_arr[rowHide], col);
  227.         ASSERT(pPaneHide != NULL);
  228.         pPaneHide->ShowWindow(SW_HIDE);
  229.  
  230.         for (int row = rowHide + 1; row < m_length; row++)
  231.         {
  232.             if (m_arr[row] < m_nRows )
  233.             {
  234.                 CWnd* pPane = CSplitterWnd::GetPane(m_arr[row], col);
  235.                 ASSERT(pPane != NULL);
  236.                 pPane->SetDlgCtrlID(Id_short(row-1, col));
  237.                 m_arr[row]--;
  238.             }
  239.         }
  240.         pPaneHide->SetDlgCtrlID(
  241.             Id_short(m_nRows -1 , col));
  242.     }
  243.  
  244.     int oldsize=m_pRowInfo[m_arr[rowHide]].nCurSize;
  245.     for (int row=rowHide;row<(m_length-1);row++)
  246.     {
  247.         if (m_arr[row+1] < m_nRows )
  248.         {
  249.             m_pRowInfo[m_arr[row]].nCurSize=m_pRowInfo[m_arr[row+1]].nCurSize;
  250.             m_pRowInfo[m_arr[row]].nIdealSize=m_pRowInfo[m_arr[row+1]].nCurSize;        
  251.         }
  252.     }
  253.     if (rowToResize!=-1)
  254.     {
  255.         m_pRowInfo[m_arr[rowToResize]].nCurSize+=oldsize+m_cySplitter;
  256.         m_pRowInfo[m_arr[rowToResize]].nIdealSize+=oldsize+m_cySplitter;
  257.         oldsize+=0x10000*(rowToResize+1);
  258.     }
  259.  
  260.     m_pRowInfo[m_nRows - 1].nCurSize =oldsize;
  261.     m_pRowInfo[m_nRows - 1].nIdealSize =oldsize;
  262.     
  263.     m_arr[rowHide] = m_nRows-1;
  264.     
  265.  
  266.     m_nRows--;
  267.     RecalcLayout();
  268. }
  269.  
  270. void CSplitterWndEx::HideColumn(int colHide, int colToResize)
  271. {
  272.     ASSERT_VALID(this);
  273.     ASSERT(m_nCols > 1);
  274.  
  275.     if (m_arr)
  276.         ASSERT(m_arr[colHide] < m_nCols);
  277.  
  278.     // if the col has an active window -- change it
  279.     int colActive, rowActive;
  280.  
  281.     if (!m_arr)
  282.     {
  283.         m_arr = new int[m_nCols];
  284.         for (int i = 0; i < m_nCols; i++)
  285.             m_arr[i] = i;
  286.         m_length = m_nCols;
  287.     }
  288.  
  289.     if (GetActivePane(&rowActive, &colActive) != NULL &&
  290.         colActive == colHide)
  291.     {
  292.         if (++colActive >= m_nCols)
  293.             colActive = 0;
  294.         SetActivePane(rowActive, colActive);
  295.     }
  296.  
  297.     // hide all row panes
  298.     for (int row = 0; row < m_nRows; row++)
  299.     {
  300.         CWnd* pPaneHide = CSplitterWnd::GetPane(row, m_arr[colHide]);
  301.         ASSERT(pPaneHide != NULL);
  302.         pPaneHide->ShowWindow(SW_HIDE);
  303.  
  304.         for (int col = colHide + 1; col < m_length; col++)
  305.         {
  306.             if (m_arr[col] < m_nCols )
  307.             {
  308.                 CWnd* pPane = CSplitterWnd::GetPane(row, m_arr[col]);
  309.                 ASSERT(pPane != NULL);
  310.                 pPane->SetDlgCtrlID(Id_short(row, col-1));
  311.                 m_arr[col]--;
  312.             }
  313.         }
  314.         pPaneHide->SetDlgCtrlID(
  315.             Id_short(row, m_nCols -1));
  316.     }
  317.  
  318.     int oldsize = m_pColInfo[m_arr[colHide]].nCurSize;
  319.     for (int col = colHide; col < (m_length - 1); ++col)
  320.     {
  321.         if (m_arr[col + 1] < m_nCols)
  322.         {
  323.             m_pColInfo[m_arr[col]].nCurSize = m_pColInfo[m_arr[col + 1]].nCurSize;
  324.             m_pColInfo[m_arr[col]].nIdealSize = m_pColInfo[m_arr[col + 1]].nCurSize;        
  325.         }
  326.     }
  327.     if (colToResize != -1)
  328.     {
  329.         m_pColInfo[m_arr[colToResize]].nCurSize += oldsize + m_cxSplitter;
  330.         m_pColInfo[m_arr[colToResize]].nIdealSize += oldsize + m_cxSplitter;
  331.         oldsize += 0x10000 * (colToResize + 1);
  332.     }
  333.  
  334.     m_pColInfo[m_nCols - 1].nCurSize = oldsize;
  335.     m_pColInfo[m_nCols - 1].nIdealSize = oldsize;
  336.     
  337.     m_arr[colHide] = m_nCols - 1;
  338.  
  339.     m_nCols--;
  340.     RecalcLayout();
  341. }
  342.  
  343. BEGIN_MESSAGE_MAP(CSplitterWndEx, CSplitterWnd)
  344. //{{AFX_MSG_MAP(CSplitterWndEx)
  345.   // NOTE - the ClassWizard will add and remove mapping macros here.
  346. //}}AFX_MSG_MAP
  347. END_MESSAGE_MAP()
  348.  
  349. CWnd* CSplitterWndEx::GetPane(int row, int col)
  350. {
  351.     if (!m_arr)
  352.         return CSplitterWnd::GetPane(row,col);
  353.     else
  354.     {
  355.         ASSERT_VALID(this);
  356.  
  357.         CWnd* pView = GetDlgItem(IdFromRowCol(m_arr[row], col));
  358.         ASSERT(pView != NULL);  // panes can be a CWnd, but are usually CViews
  359.         return pView;
  360.     }
  361. }
  362.  
  363. int CSplitterWndEx::IdFromRowCol(int row, int col) const
  364. {
  365.     ASSERT_VALID(this);
  366.     ASSERT(row >= 0);
  367.     ASSERT(row < (m_arr?m_length:m_nRows));
  368.     ASSERT(col >= 0);
  369.     ASSERT(col < m_nCols);
  370.  
  371.     return AFX_IDW_PANE_FIRST + row * 16 + col;
  372. }
  373.  
  374. BOOL CSplitterWndEx::IsChildPane(CWnd* pWnd, int* pRow, int* pCol)
  375. {
  376.     ASSERT_VALID(this);
  377.     ASSERT_VALID(pWnd);
  378.  
  379.     UINT nID = ::GetDlgCtrlID(pWnd->m_hWnd);
  380.     if (IsChild(pWnd) && nID >= AFX_IDW_PANE_FIRST && nID <= AFX_IDW_PANE_LAST)
  381.     {
  382.         if (pWnd->GetParent()!=this)
  383.             return FALSE;
  384.         if (pRow != NULL)
  385.             *pRow = (nID - AFX_IDW_PANE_FIRST) / 16;
  386.         if (pCol != NULL)
  387.             *pCol = (nID - AFX_IDW_PANE_FIRST) % 16;
  388.         ASSERT(pRow == NULL || *pRow < (m_arr?m_length:m_nRows));
  389.         ASSERT(pCol == NULL || *pCol < m_nCols);
  390.         return TRUE;
  391.     }
  392.     else
  393.     {
  394.         if (pRow != NULL)
  395.             *pRow = -1;
  396.         if (pCol != NULL)
  397.             *pCol = -1;
  398.         return FALSE;
  399.     }
  400. }
  401.  
  402. CWnd* CSplitterWndEx::GetActivePane(int* pRow, int* pCol)
  403.     // return active view, NULL when no active view
  404. {
  405.     ASSERT_VALID(this);
  406.  
  407.     // attempt to use active view of frame window
  408.     CWnd* pView = NULL;
  409.     CFrameWnd* pFrameWnd = GetParentFrame();
  410.     ASSERT_VALID(pFrameWnd);
  411.     pView = pFrameWnd->GetActiveView();
  412.  
  413.     // failing that, use the current focus
  414.     if (pView == NULL)
  415.         pView = GetFocus();
  416.  
  417.     // make sure the pane is a child pane of the splitter
  418.     if (pView != NULL && !IsChildPane(pView, pRow, pCol))
  419.         pView = NULL;
  420.  
  421.     return pView;
  422. }
  423.  
  424. BOOL CSplitterWndEx::IsRowHidden(int row)
  425. {
  426.     return m_arr[row]>=m_nRows;
  427.  
  428. }
  429.  
  430. void CSplitterWndEx::GetRowInfoEx(int row, int &cyCur, int &cyMin)
  431. {
  432.     if (!m_arr)
  433.         GetRowInfo(row,cyCur,cyMin);
  434.     else
  435.     {
  436.         if (m_pRowInfo[m_arr[row]].nCurSize>0x10000)
  437.             cyCur=m_pRowInfo[m_arr[row]].nCurSize/0x10000;
  438.         else
  439.             cyCur=m_pRowInfo[m_arr[row]].nCurSize%0x10000;
  440.         cyMin=0;
  441.     }
  442. }
  443.  
  444. __int64 CSplitterWndEx::GetSizes() const
  445. {
  446.     LARGE_INTEGER v;
  447.     int dummy;
  448.     int s1, s2;
  449.     if (BarIsHorizontal())
  450.     {
  451.         GetRowInfo(0, s1, dummy);
  452.         GetRowInfo(1, s2, dummy);
  453.         v.HighPart = s1;
  454.         v.LowPart = s2;
  455.     }
  456.     else
  457.     {
  458.         GetColumnInfo(0, s1, dummy);
  459.         GetColumnInfo(1, s2, dummy);
  460.         v.HighPart = s1;
  461.         v.LowPart = s2;
  462.     }
  463.     return v.QuadPart;
  464. }
  465.